package com.shop.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.admin.dao.ShopCategoryDao;
import com.shop.admin.entity.ShopCategory;
import com.shop.admin.entity.ShopImage;
import com.shop.admin.entity.ShopOrder;
import com.shop.admin.service.ShopCategoryService;
import com.shop.admin.service.ShopImageService;
import com.shop.admin.service.ShopOrderService;
import com.shop.admin.service.ShopStockService;
import com.shop.admin.utils.PageUtils;
import com.shop.admin.utils.Query;
import com.shop.admin.vo.CateOrderListVo;
import com.shop.admin.vo.CategoryVo;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryDao, ShopCategory> implements ShopCategoryService {

    @Autowired
    private ShopOrderService shopOrderService;

    @Autowired
    private ShopImageService shopImageService;

    @Autowired
    private ShopStockService stockService;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;


    @Override
    //@Cacheable(value = {"category"},key = "'getCategorys'",sync = true)
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ShopCategory> page = this.page(
                new Query<ShopCategory>().getPage(params),
                new QueryWrapper<ShopCategory>().lambda().eq(ShopCategory::getOrgId,params.get("orgId"))
        );
        return new PageUtils(page);
    }

    @Override
    @SneakyThrows
    public List<CategoryVo>  queryPageByCate(Map<String, Object> params) {
        CompletableFuture<List<ShopCategory>> shopCategoryListCompletableFuture = CompletableFuture.supplyAsync(() -> {

            List<ShopCategory> shopCategoryList = this.baseMapper.selectList(new QueryWrapper<ShopCategory>());
            if (CollectionUtils.isEmpty(shopCategoryList)) {
                return Collections.emptyList();
            }
            return shopCategoryList;
        }, threadPoolExecutor);

        List<ShopCategory> shopCategoryList = shopCategoryListCompletableFuture.get();

            List<CategoryVo> collect = shopCategoryList.parallelStream().map(item -> {
                CategoryVo categoryVO = new CategoryVo();
                BeanUtils.copyProperties(item, categoryVO);
                return categoryVO;
            }).collect(Collectors.toList());

            CompletableFuture.allOf(shopCategoryListCompletableFuture);
            return collect;
    }

    @Override
    //@CacheEvict(value = "category",allEntries = true)
    public void updateCascade(ShopCategory category){
        category.setUpdateTime(new Date());
        this.updateById(category);
    }

    @SneakyThrows
    @Override
    public List<CateOrderListVo> selectOrderList(Long cateId) {
        CompletableFuture<List<ShopOrder>> shopOrderListCompletableFuture = CompletableFuture.supplyAsync(() -> {
            List<ShopOrder> shopOrderList = shopOrderService.list(
                    new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getCatelogId, cateId)
            );
            if (CollectionUtils.isEmpty(shopOrderList)) {
                return Collections.emptyList();
            }
            return shopOrderList;
        }, threadPoolExecutor);

        List<ShopOrder> shopOrderList = shopOrderListCompletableFuture.get();

        List<CateOrderListVo> collect = shopOrderList.parallelStream().map(item -> {
            CateOrderListVo cateOrderListVO = new CateOrderListVo();
            cateOrderListVO.setOrderId(item.getOrderId());
            cateOrderListVO.setOrderName(item.getOrderName());

            CompletableFuture<List<ShopImage>> imageListCompletableFuture = CompletableFuture.supplyAsync(() -> {
                List<ShopImage> imageList = shopImageService.selectOrderImages(item.getOrderId().intValue());
                if (CollectionUtils.isEmpty(imageList)) {
                    return Collections.emptyList();
                }
                return imageList;
            }, threadPoolExecutor);

            List<ShopImage> imageList = null;
            try {
                imageList = imageListCompletableFuture.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            cateOrderListVO.setImagesList(imageList.parallelStream().map(img->{
                return img.getImgUrl();
            }).collect(Collectors.toList()));
            return cateOrderListVO;
        }).collect(Collectors.toList());

        CompletableFuture.allOf(shopOrderListCompletableFuture);
        return collect;
    }

    @Override
    @Transactional
    //@CacheEvict(value = "category",allEntries = true)
    public void removeCategoryByIds(List<Long> asList) {

        for (Long aLong : asList) {
            List<ShopOrder> shopOrders = shopOrderService.list(new LambdaQueryWrapper<ShopOrder>().eq(ShopOrder::getCatelogId, aLong));
            for (ShopOrder shopOrder1 : shopOrders) {
                ShopOrder shopOrder = new ShopOrder();
                shopOrder.setOrderId(shopOrder1.getOrderId());
                shopOrder.setTombstone(0);
                shopOrderService.updateById(shopOrder);
            }
        }
//        CompletableFuture<Void> deleteBatchIdsCompletableFuture = CompletableFuture.runAsync(() -> {
//            this.baseMapper.deleteBatchIds(asList);
//        }, threadPoolExecutor);
//
//        CompletableFuture<Void> removeOrdersByIdsCompletableFuture = CompletableFuture.runAsync(() -> {
//            shopOrderService.removeOrdersByIds(asList);
//        }, threadPoolExecutor);

//        CompletableFuture<Void> removeByIdsCompletableFuture = CompletableFuture.runAsync(() -> {
//            stockService.removeByIds(asList);
//        }, threadPoolExecutor);
//
//        CompletableFuture<Void> removeImagesByOrderIdCompletableFuture = CompletableFuture.runAsync(() -> {
//            shopImageService.removeImagesByOrderId(asList);
//        }, threadPoolExecutor);

//        CompletableFuture.allOf(deleteBatchIdsCompletableFuture,removeOrdersByIdsCompletableFuture);
    }

    @Override
    public ShopCategory selectById(Integer catelogId) {
        return this.baseMapper.selectById(catelogId);
    }

    @Override
    //@CacheEvict(value = "category",allEntries = true)
    public boolean selectBoolean(String cateName,Integer orgId) {
        if (this.baseMapper.selectOne(new QueryWrapper<ShopCategory>().lambda().eq(ShopCategory::getOrgId,orgId).eq(ShopCategory::getCateName,cateName))!=null){
            return false;
        }
        return true;
    }

}
